//
//  MonsterDen.cpp
//  fingeradvanture
//
//  Created by shuaibincheng on 16/5/1.
//
//

#include "MonsterDen.hpp"
#include "Utils.hpp"
#include "MonsterTroopFactory.hpp"

MonsterDen *MonsterDen::den = 0;

MonsterDen *MonsterDen::getInstance()
{
    if(!den)
    {
        den = new MonsterDen;
    }
    return den;
}

MonsterDen::MonsterDen()
{
    this->waitingMonsters = new Vector<Node*>;
    this->fightingMonster = new Vector<Node*>;
}

MonsterDen::~MonsterDen()
{
    CC_SAFE_DELETE(this->waitingMonsters);
    CC_SAFE_DELETE(this->fightingMonster);
}

Vector<Node *> MonsterDen::decideToSendTroops(b2World* world)
{
    if(!this->foundHero)
        return Vector<Node *>(0);
    
    if(!this->fightingMonster->size())
    {
        auto troops = MonsterTroopFactory::getInstance()->spawn(world);
        
        for(auto it = troops.begin(); it != troops.end(); it++)
        {
            fightingMonster->pushBack(*it);
        }
        
        return troops;
    }
    
    Vec2 lastTroopPosition = (*fightingMonster->rbegin())->getPosition();
    Size visibleSize = Director::getInstance()->getVisibleSize();
    if(lastTroopPosition.y < visibleSize.height / 2)
    {
        //CCLOG("decide to send a new troop");
        auto troops = MonsterTroopFactory::getInstance()->spawn(world);
        
        for(auto it = troops.begin(); it != troops.end(); it++)
        {
            fightingMonster->pushBack(*it);
        }
        
        return troops;
    }
    return Vector<Node *>(0);
}

void MonsterDen::recycleUselessTroops(b2World* world)
{
    if(fightingMonster->empty())
        return;
    
    Vector<Node*>::iterator it = fightingMonster->begin();
    for(; it != fightingMonster->end(); it++)
    {
        
        Vec2 position = (*it)->getPosition();
        auto maxY = position.y + (*it)->getContentSize().height * (*it)->getAnchorPoint().y;
        if(maxY < 0)
        {
            b2Body* body = NULL;
            for(b2Body *b = world->GetBodyList();b; b = b->GetNext())
            {
                if(b->GetUserData() != NULL)
                {
                    Sprite* sprite = (Sprite*)b->GetUserData();
                    if((Sprite*)*it == sprite)
                    {
                        body = b;
                    }
                    
                }
            }
            if(body != NULL)
            {
                world->DestroyBody(body);
            }
            (*it)->stopAllActions();
            (*it)->removeFromParent();
            (*it)->release();
            fightingMonster->erase(it);
        }
    }
    //CCLOG("we still have %zd troops to fight", fightingMonster->size());
}


Node *MonsterDen::callOfDuty(b2World *world, MonsterType type)
{
    //从waitingMonsters队列中获取一个同类的monster
    
    Node *candidate = 0;
    Vector<Node *>::iterator it = waitingMonsters->begin();
    for(; it != waitingMonsters->end(); it++)
    {
        MonsterUserData *data = (MonsterUserData *)(*it)->getUserData();
        if(!data)
        {
            CCLOG("有一个未知类型的monster, 或许是人类派来的间谍");
            continue;
        }
        if(data->getType() == type)
        {
            candidate = (*it);
            break;
        }
    }
    if(!candidate)
    {
        //在等待的怪物中找不到同类的怪物, 需要生成一个
        //to do...
        candidate = Utils::createTestTroop(world, type);
        MonsterUserData *data = new MonsterUserData();
        data->setType(type);
        candidate->setUserData(data);
        candidate->retain();
    }
    return candidate;
}

void MonsterDen::notifyHeroEntered()
{
    //a damn hero has arrived, let's kill him.
    this->foundHero = true;
}

void MonsterDen::notifyHeroExited()
{
    //the hero has already leaved, so we can have some rest
    this->foundHero = false;
}

Node *createTestTroop()
{
    return 0;
}